package com.carleasoft.mps.core.utils;

import cn.hutool.core.util.StrUtil;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.InputFormatException;
import it.sauronsoftware.jave.MultimediaInfo;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.UUID;

/**
 * @author taoyujing
 * @date 2022-01-11 10:10
 * @project 视频工具类
 */
public class VideoUtil {
    /**
     * 通过MultipartFile 的文件类型获取视频时长
     * @param file
     * @return
     */
    public Integer ReadVideoTimeMs(MultipartFile file) {
        Encoder encoder = new Encoder();
        long ms = 0;
        try {
            // 获取文件类型
            String fileName = file.getContentType();
            // 获取文件后缀
            assert fileName != null;
            String pref = fileName.contains("/") ? fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length()) : null;
            String prefix = "." + pref;
            // 用uuid作为文件名，防止生成的临时文件重复
            final File excelFile = File.createTempFile(UUID.randomUUID().toString().replace("-", ""), prefix);
            // MultipartFile to File
            file.transferTo(excelFile);
            MultimediaInfo m = encoder.getInfo(excelFile);
            ms = m.getDuration();
            //程序结束时，删除临时文件
            VideoUtil.deleteFile(excelFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int ss = 1000;
        int mi = ss * 60;
        int hh = mi * 60;
        int dd = hh * 24;

        long day = ms / dd;
        long hour = (ms - day * dd) / hh;
        long minute = (ms - day * dd - hour * hh) / mi;
        long second = (ms - day * dd - hour * hh - minute * mi) / ss;

        return Math.toIntExact(hour * 3600 + minute * 60 + second);
    }

    private static void deleteFile(File... files) {
        for (File file : files) {
            if (file.exists()) {
                file.delete();
            }
        }
    }


    /**
     * 根据传入的MultipartFile进行计算视频的播放时长
     * @param contentFile
     * @return
     * @throws InputFormatException
     * @throws EncoderException
     */
    public static String getVideoTime(MultipartFile contentFile) throws Exception {
        // 将MultipartFile转换为临时文件File

        File dfile = null;
        try {
            dfile = File.createTempFile("prefix", "_" + contentFile.getOriginalFilename());
            System.out.println(dfile.getPath());
            contentFile.transferTo(dfile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取视频时长
        Encoder encoder = new Encoder();
        MultimediaInfo m = encoder.getInfo(dfile);
        long ls = m.getDuration()/1000;
        int hour = (int) (ls/3600);
        int minute = (int) (ls%3600)/60;
        int second = (int) (ls-hour*3600-minute*60);
        //删除临时文件
        VideoUtil.deleteFile(dfile);
        return hour + ":" + minute + ":" + second ;
    }



/*    public static void main(String[] args) throws Exception {
        File file = new File("D:\\test-html\\8162ca268dfbcc23e0e9f5fa56b4a667.mp4");
        FileInputStream fileInputStream = new FileInputStream(file);
        MockMultipartFile mockMultipartFile = new MockMultipartFile(file.getName(), fileInputStream);
        String videoTime = VideoUtil.getVideoTime(mockMultipartFile);
        System.out.println(videoTime);
*//*        MultipartFile multipartFile = VideoUtil.fetchFrame(mockMultipartFile);
        System.out.println(multipartFile.getOriginalFilename());
        System.out.println(multipartFile.getSize());
        System.out.println(multipartFile.getName());*//*
//        System.out.println(System.getProperty("java.library.path"));
    }*/

    public static File directoryFile(){
        String tempDir = System.getProperty("user.dir");
        //存放--服务器上zip文件的目录
        String directory = tempDir + StrUtil.BACKSLASH + "repository";
        File directoryFile = new File(directory);
        if (!directoryFile.exists() || !directoryFile.isDirectory()) {
            directoryFile.mkdirs();
        }
        return directoryFile;
    }

    public static MultipartFile fetchFrame(MultipartFile file)
            throws Exception {
        //获取当前系统时间，类似new Date()，效率比较好
        //储存截图的文件

        File framefile   = null;
        try {
            framefile   = File.createTempFile(UUID.randomUUID().toString(), ".png",VideoUtil.directoryFile());
            file.transferTo(framefile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        File videofile   = null;
        try {
            videofile   = File.createTempFile("prefix", "_" + file.getOriginalFilename(),VideoUtil.directoryFile());
            System.out.println(videofile.getPath());
            file.transferTo(videofile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //FFmpegFrameGrabb读取时间随机截图类
        assert videofile != null;
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile.getPath());
        ff.start();

        // 表示视频的总图片数量
        int lenght = ff.getLengthInFrames();
        int i = 0;
        Frame f = null;
        while (i < lenght) {
            // 过滤前5帧，避免出现全黑的图片，依自己情况而定
            f = ff.grabFrame();
            if ((i > 5) && (f.image != null)) {
                break;
            }
            i++;
        }
        Java2DFrameConverter converter =new Java2DFrameConverter();
        BufferedImage output =converter.getBufferedImage(f);
        ImageIO.write(output,"png", framefile);

        FileInputStream fileInputStream = new FileInputStream(framefile);
        MockMultipartFile mockMultipartFile = new MockMultipartFile("File",framefile.getName(),"text/plain", fileInputStream);
        VideoUtil.deleteFile(framefile);
        VideoUtil.deleteFile(videofile);
        return mockMultipartFile;
    }



}
